package vcp.client.GUI.mvc.view.effects;

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;

import javax.swing.JComponent;
import javax.swing.JLayer;
import javax.swing.Timer;
import javax.swing.plaf.LayerUI;
/**
 * <p> wait layer user interface class </p>
 * @author VCP team
 *
 */
public class WaitLayerUI extends LayerUI <JComponent> implements ActionListener
{
	/**
	 * 
	 */
	private static final long serialVersionUID = 2012332038896112295L;
	private boolean isRunning;
	private boolean isFadingOut;
	private Timer timer;

	private static final String TICK = "tick";

	private int mAngle;
	private int mFadeCount;
	private final int mFadeLimit = 15;

	@Override
	public void paint ( Graphics g, JComponent c )
	{
		int w = c.getWidth();
		int h = c.getHeight();

		// Paint the view.
		super.paint(g, c);

		if ( ! this.isRunning )
		{
			return;
		}

		Graphics2D g2 = (Graphics2D) g.create();

		float fade = (float) this.mFadeCount / (float) this.mFadeLimit;
		// Gray it out.
		Composite urComposite = g2.getComposite();
		g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .5f * fade));
		g2.fillRect(0, 0, w, h);
		g2.setComposite(urComposite);

		// Paint the wait indicator.
		int s = Math.min(w, h) / 5;
		int cx = w / 2;
		int cy = h / 2;
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		g2.setStroke(new BasicStroke(s / 4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
		g2.setPaint(Color.white);
		g2.rotate(Math.PI * this.mAngle / 180, cx, cy);
		for ( int i = 0; i < 12; i ++ )
		{
			float scale = ( 11.0f - i ) / 11.0f;
			g2.drawLine(cx + s, cy, cx + s * 2, cy);
			g2.rotate( - Math.PI / 6, cx, cy);
			g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, scale * fade));
		}

		g2.dispose();
	}

	@Override
	public void actionPerformed ( ActionEvent e )
	{
		if ( this.isRunning )
		{
			this.firePropertyChange(WaitLayerUI.TICK, 0, 1);
			this.mAngle += 30;
			if ( this.mAngle >= 360 )
			{
				this.mAngle = 0;
			}
			if ( this.isFadingOut )
			{
				if ( -- this.mFadeCount == 0 )
				{
					this.isRunning = false;
					this.timer.stop();
				}
			}
			else if ( this.mFadeCount < this.mFadeLimit )
			{
				this.mFadeCount ++ ;
			}
		}
	}
	/** 
	 * runs wait layer UI
	 */
	public void start ()
	{
		if ( this.isRunning )
		{
			return;
		}

		// Run a thread for animation.
		this.isRunning = true;
		this.isFadingOut = false;
		this.mFadeCount = 0;
		int fps = 24;
		int tick = 1000 / fps;
		this.timer = new Timer(tick, this);
		this.timer.start();
	}
	/**
	 * stops wait layer UI
	 */
	public void stop ()
	{
		this.isFadingOut = true;
	}

	@SuppressWarnings ( "rawtypes" )
	@Override
	public void applyPropertyChange ( PropertyChangeEvent pce, JLayer l )
	{
		if ( WaitLayerUI.TICK.equals(pce.getPropertyName()) )
		{
			l.repaint();
		}
	}
}
